import { PropType, computed, defineComponent, inject, onMounted, ref, watchEffect } from "vue";
import { ColumnProps, TableContextKey } from ".";
import Checkbox from "../inner/Checkbox";
import { FeatherChevronDown, FeatherChevronRight, FeatherChevronUp, FeatherMinusSquare, FeatherPlusSquare } from "cui-vue-icons/feather";
import dayjs from "dayjs";
import Popover from "../Popover";

export default defineComponent({
    name: "Cell",
    props: {
        column: {type: Object as PropType<ColumnProps>},
        colIndex: {type: Number},
        type: {type: String},
        showFixedLeft: {type: Boolean},
        showFixedRight: {type: Boolean},
        placeholder: {type: Boolean},
        data: {type: Object},
        index: {type: Number},
        checkedAll: {type: [Boolean, String]},
        colSpan: {type: Number},
        rowSpan: {type: Number},
        summary: {type: Boolean},
    },
    setup (props) {
        const cell = ref();
        const col: ColumnProps = props.column;
        const colIndex: number = props.colIndex;
        const ctx: any = inject(TableContextKey, null);
        onMounted(()=>{
            setTimeout(() => {
                updateCellStyle();
            });
        });

        const cellClassList = computed(() => ({
            'cm-table-head-col': props.type === 'th',
            'cm-table-cell-fixed-left-last': col.fixedLeftLast && props.showFixedLeft,
            'cm-table-cell-fixed-right-first': col.fixedRightFirst && props.showFixedRight,
        }));

        const updateCellStyle = () => {
            if (col.fixed && cell.value && !props.placeholder) {
                if (col.fixed === 'left') {
                    cell.value.style.position = 'static';
                    const parent = cell.value.closest('.cm-table');
                    if (parent) {
                        const head = parent.querySelector('thead');
                        let left = 0;
                        for (let i = 1; i <= colIndex; i++) {
                            const th = head.querySelector('th:nth-child('+i+')');
                            if (th) {
                                left += th.getBoundingClientRect().width;
                            }
                        }

                        cell.value.style.position = 'sticky';
                        cell.value.style.left = left + 'px';
                        cell.value.style.zIndex = props.type === 'th' ? 3 : 1;
                        cell.value.classList.add('cm-table-cell-fixed-left');
                        if (col.fixedLeftLast && props.showFixedLeft) {
                            cell.value.classList.add('cm-table-cell-fixed-left-last');
                        }
                    }
                }
                if (col.fixed === 'right') {
                    const parent = cell.value.closest('.cm-table');
                    if (parent) {
                        const head = parent.querySelector('thead');
                        const length = head.querySelectorAll('th').length;

                        let w = 0;
                        for (let i = colIndex + 2; i <= length; i++) {
                            const th = head.querySelector('th:nth-child('+i+')');
                            w += th.getBoundingClientRect().width;
                        }

                        cell.value.style.position = 'sticky';
                        cell.value.style.right = w + 'px';
                        cell.value.style.zIndex = props.type === 'th' ? 3 : 1;
                        cell.value.classList.add('cm-table-cell-fixed-right');
                        if (col.fixedRightFirst && props.showFixedRight) {
                            cell.value.classList.add('cm-table-cell-fixed-right-first');
                        }
                    }
                }
            }
        };

        watchEffect(() => {
            col.width;
            col._;
            updateCellStyle();
        });

        // 树型图标
        const treeIcon = () => {
            return props.data._showChildren
                ? <FeatherMinusSquare class="cm-table-tree-icon" strokeWidth={1} onClick={onShowChildren}/>
                : <FeatherPlusSquare class="cm-table-tree-icon" strokeWidth={1} onClick={onShowChildren}/>;;
        };

        // 选择框选择事件
        const onRowChecked = (checked: boolean) => {
            ctx?.onRowChecked(props.data, checked);
        };

        // 头部选择框选择事件
        const onHeadChecked = (checked: boolean) => {
            ctx?.onHeadChecked(checked);
        };

        // 点击排序
        const onSort = (sortType: string) => {
            ctx?.onSort(col, sortType);
        };

        // 点击树型展开图标
        const onShowChildren = () => {
            ctx?.onShowChildren(props.data);
        };

        // 展开
        const onExpand = () => {
            ctx?.onExpand(col, props.data);
        };

        // onDragStart
        const onDragStart = (e: any) => {
            ctx?.onDragStart(col, e);
        };

        const text = computed(() => {
            const column = props.column;
            if (props.type === 'td') {
                if (props.summary) {
                    return props.data[column.name];
                }
                if (column.type === 'index') {
                    return props.index + 1;
                }
                if (column.type === 'date') {
                    return dayjs(props.data[column.name]).format('YYYY-MM-DD');
                }
                if (column.type === 'datetime') {
                    return dayjs(props.data[column.name]).format('YYYY-MM-DD HH:mm:ss');
                }
                if (column.type === 'enum') {
                    return column.enum?.[props.data[column.name]];
                }
                if (column.type === 'checkbox') {
                    return <Checkbox disabled={props.data._disabled} checked={props.data._checked} onChange={onRowChecked}/>;
                }
                if (props.data._type === 'expandChildren') {
                    return props.data.render ? props.data.render() : null;
                }
                if (column.type === 'expand') {
                    return <FeatherChevronRight class={`cm-table-expand ${props.data._expand ? 'cm-table-expand-open' : ''}`} onClick={onExpand}/>;
                }
                if (column.render && typeof column.render === 'function') {
                    return column.render({value: props.data[column.name], column, record: props.data, index: props.index});
                }
                return props.data[column.name];
            } else {
                if (column.type === 'checkbox') {
                    return <Checkbox checked={props.checkedAll} onChange={onHeadChecked}/>;
                }
                return props.column.title;
            }
        });

        return () => props.type === 'th' ?
            <th ref={cell} class={cellClassList.value} colspan={props.colSpan} rowspan={props.rowSpan} data-index={props.colIndex}>
                <div class="cm-table-cell">
                    {text.value}
                    {
                        col.sort ? <span class="cm-table-sort">
                            <FeatherChevronUp class={col.sortType === 'asc' ? 'cm-table-sort-active' : ''} onClick={onSort.bind(null, 'asc')}/>
                            <FeatherChevronDown class={col.sortType === 'desc' ? 'cm-table-sort-active' : ''} onClick={onSort.bind(null, 'desc')}/>
                        </span>
                            : null
                    }
                    {
                        col.resize && col.width && ctx && ctx.border
                            ? <span class="cm-table-resize" onMousedown={onDragStart}></span>
                            : null
                    }
                </div>
            </th>
            : <td ref={cell} class={cellClassList.value} colspan={props.colSpan} rowspan={props.rowSpan}>
                <div class="cm-table-cell">
                    {
                        col.tree ? <>
                            <span class="cm-table-tree-level" style={{"padding-left": `${props.data._level * 16}px`}}></span>
                            {
                                props.data.children && props.data.children.length ?
                                    treeIcon()
                                    : <span class="cm-table-tree-icon-empty"></span>
                            }
                        </>
                            : null
                    }
                    {
                        col.ellipsis || col.tooltip
                            ? col.tooltip ? <Popover arrow align={col.tooltipAlign || 'top'} theme={col.tooltipTheme}
                                class="cm-table-cell-tooltip"
                                style={{...col.tooltipStyle, "max-width": `${col.tooltipMaxWidth || 200}px`}}
                                content={<div>{text.value}</div>}>
                                <span class="cm-table-cell-tooltip-content">{text.value}</span>
                            </Popover>
                                : <span class="cm-table-cell-ellipsis">{text.value}</span>
                            : text.value
                    }
                </div>
            </td>;
    }
});
